package org.wisigoth.chat.swing;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;

import org.wisigoth.chat.client.ConnectionEvent;
import org.wisigoth.chat.client.ConnectionStateListener;
import org.wisigoth.chat.client.DefaultPresence;
import org.wisigoth.chat.client.Presence;
import org.wisigoth.chat.client.Session;
import org.wisigoth.chat.client.Session.ConnectionState;


public final class WisigothSystemTray {
	
	private static WisigothSystemTray instance = null;
	
	private boolean installed = false;
	private Image onlineImage;
	private Image offLineImage;
	private Session session;
	private TrayIcon iconTray;
	private PopupMenu popupMenu;
	private Menu presenceMenu;
	private MenuItem contactListMenu;
	
	private WisigothSystemTray(Session session){
		this.session = session;
		URL imageTrayURL = WisigothSystemTray.class.getResource("/images/online.png");
		this.onlineImage = Toolkit.getDefaultToolkit().getImage(imageTrayURL);
		imageTrayURL = WisigothSystemTray.class.getResource("/images/offline.png");
		this.offLineImage = Toolkit.getDefaultToolkit().getImage(imageTrayURL);
		this.iconTray = new TrayIcon(this.offLineImage, "Wisigoth", this.createPopupMenu());
		this.session.addConnectionStateListener(new ConnectionListener());
		
	}
	
	private PopupMenu createPopupMenu(){
		this.popupMenu = new PopupMenu();
		this.presenceMenu = new Menu("Presence");
		PresenceMenuListener presenceListener = new PresenceMenuListener();
		for (Presence presence : DefaultPresence.values()) {
			PresenceMenuItem menu = new PresenceMenuItem(presence);
			menu.addActionListener(presenceListener);
			this.presenceMenu.add(menu);
		}

		this.contactListMenu = new MenuItem("Contact List");
		MenuItem quitMenu = new MenuItem("Quit");
		this.popupMenu.add(this.contactListMenu);
		this.popupMenu.add(this.presenceMenu);
		this.popupMenu.add(quitMenu);
		return this.popupMenu;
	}
	
	public static WisigothSystemTray getInstance(Session session){
		if(instance == null){
			instance = new WisigothSystemTray(session);
		}
		return instance;
	}
	
	public PopupMenu getPopupMenu() {
		return this.popupMenu;
	}
	
	public TrayIcon getTrayIcon() {
		return this.iconTray;
	}
	
	public void setMenuOffline() {
		this.presenceMenu.setEnabled(false);
		this.contactListMenu.setEnabled(false);
	}
	
	public void setMenuOnline() {
		this.presenceMenu.setEnabled(true);
		this.contactListMenu.setEnabled(true);
	}

	public void install(){
		if(!this.installed){
			try {
				SystemTray.getSystemTray().add(this.iconTray);
				this.installed = true;
			} catch (AWTException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void uninstall(){
		if(this.installed){
			SystemTray.getSystemTray().remove(this.iconTray);
			this.installed = false;
			
		}
		
	}
	
	private class ConnectionListener implements ConnectionStateListener {

		@Override
		public void connectionStateChanged(ConnectionEvent event) {
			ConnectionState state = WisigothSystemTray.this.session.getConnectionState();
			if (state == ConnectionState.OFFLINE) {
				WisigothSystemTray.this.iconTray.setImage(WisigothSystemTray.this.offLineImage);
				WisigothSystemTray.this.setMenuOffline();
				
			} else {
				WisigothSystemTray.this.iconTray.setImage(WisigothSystemTray.this.onlineImage);
				WisigothSystemTray.this.setMenuOnline();
			}
		}

	}
	
	
	private class PresenceMenuListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			PresenceMenuItem menu = (PresenceMenuItem)e.getSource();
			Presence presence = menu.getPresence();
			WisigothSystemTray.this.session.setPresence(presence);
		}
	}
	

	private static class PresenceMenuItem extends MenuItem {
		
		private Presence presence;

		public PresenceMenuItem(Presence presence){
			super(presence.getPresenceName());
			this.presence = presence;
		}
		
		public Presence getPresence(){
			return this.presence;
		}
	}
	
}
